package com.flyme.common.rpc.spring.handler;

import com.flyme.common.rpc.support.ServiceManager;
import com.flyme.common.rpc.support.ServiceMetadata;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @author liyanxin
 */
public abstract class AbstractInvocationHandler implements InvocationHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractInvocationHandler.class);

    public void before(String className, String methodName, Object[] args) {
        LOGGER.info("class[{}],method[{}],with args[{}] start...", className, methodName, args);
    }

    public void after(String className, String methodName, Object[] args, long startTime, Object result) {
        long current = System.currentTimeMillis();
        LOGGER.info("class[{}],method[{}],with args[{}],with result[{}],finish,spend time:{}", className, methodName, args, result, current - startTime);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = null;
        if (!StringUtils.equals(method.getName(), "toString")) {
            String fullName = method.getDeclaringClass().getName() + "." + method.getName();
            ServiceMetadata serviceMetadata = ServiceManager.getInstance().get(fullName);
            if (serviceMetadata != null) {
                before(serviceMetadata.getInterfaceName(), method.getName(), args);
                result = doInvoke(serviceMetadata, args);
                after(serviceMetadata.getInterfaceName(), method.getName(), args, startTime, result);
            }
        }

        return result;
    }

    public abstract Object doInvoke(ServiceMetadata serviceMetadata, Object[] args);
}
